#region AuditFunctions

	#region User Accounts
	
		function Test-UserCredential 
		{
			<#
				.SYNOPSIS
					Validates credentials for local or domain user.
				
				.PARAMETER  Username
					The user's username.
			
				.PARAMETER  Password
					The user's password.
					
				.PARAMETER  Credential
					A PSCredential object created by Get-Credential. This can be pipelined to Test-UserCredential.

				.PARAMETER  Domain
					If this flag is set the user credentials should be a domain user account.
					
				.PARAMETER  UseKerberos
					By default NTLM is used. Specify this switch to attempt kerberos authentication. 
					
					This is only used with the 'Domain' parameter.
					
					You may need to specify domain\user.
			
				.EXAMPLE
					PS C:\> Test-UserCredential -Username andy -password (Read-Host -AsSecureString)
			
				.EXAMPLE
					PS C:\> Test-UserCredential -Username 'mydomain\andy' -password (Read-Host -AsSecureString) -domain -UseKerberos

				.EXAMPLE
					PS C:\> Test-UserCredential -Username 'andy' -password (Read-Host -AsSecureString) -domain
					
				.EXAMPLE
					PS C:\> Get-Credential | Test-UserCredential
			
				.INPUTS
					None.
			
				.OUTPUTS
					System.Boolean.

				.LINK
					http://msdn.microsoft.com/en-us/library/system.directoryservices.accountmanagement.principalcontext.aspx
					
				.LINK
					http://poshcode.org/2927
			
				.NOTES
					Author: Andy Arismendi
					Revision History
						2011-08-21: Andy Arismendi - Created.
						2011-08-22: Andy Arismendi - Add pipelining support for Get-Credential.
						2011-08-22: Andy Arismendi - Add support for NTLM/kerberos switch.	
			#>			
		
			[CmdletBinding(DefaultParameterSetName = "set1")]
			[OutputType("set1", [System.Boolean])]
			[OutputType("PSCredential", [System.Boolean])]
			param(
				[Parameter(Mandatory=$true, ParameterSetName="set1", position=0)] 
				[ValidateNotNullOrEmpty()]
				[String] $Username,

				[Parameter(Mandatory=$true, ParameterSetName="set1", position=1)] 
				[ValidateNotNullOrEmpty()]
				[System.Security.SecureString] $Password,
				
				[Parameter(Mandatory=$true, ParameterSetName="PSCredential", ValueFromPipeline=$true, position=0)] 
				[ValidateNotNullOrEmpty()]
				[Management.Automation.PSCredential] $Credential,
				
				[Parameter(position=2)]
				[Switch] $Domain,
				
				[Parameter(position=3)]
				[Switch] $UseKerberos
			)
			
			Begin {
				try { $assem = [system.reflection.assembly]::LoadWithPartialName('System.DirectoryServices.AccountManagement') }
				catch { throw 'Failed to load assembly "System.DirectoryServices.AccountManagement". The error was: "{0}".' -f $_ }
				
				$system = Get-WmiObject -Class Win32_ComputerSystem
				
				if (0, 2 -contains $system.DomainRole -and $Domain) {
					throw 'This computer is not a member of a domain.'
				}
			}
			
			Process {
				try {
					switch ($PSCmdlet.ParameterSetName) {
						'PSCredential' {
							if ($Domain) {
								$Username = $Credential.UserName.TrimStart('\')
							} else {
								$Username = $Credential.GetNetworkCredential().UserName
							}
							$PasswordText = $Credential.GetNetworkCredential().Password
						}
						'set1' {
								# Decrypt secure string.
							$PasswordText = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
									[Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password)
								)
						}
					}
							
					if ($Domain) {
						$pc = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext 'Domain', $system.Domain
					} else {
						$pc = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext 'Machine', $env:COMPUTERNAME
					}
					
					if ($Domain -and $UseKerberos) {
						return $pc.ValidateCredentials($Username, $PasswordText)
					} else {
						return $pc.ValidateCredentials($Username, $PasswordText, [DirectoryServices.AccountManagement.ContextOptions]::Negotiate)
					}
				} catch {
					throw 'Failed to test user credentials. The error was: "{0}".' -f $_
				} finally {
					Remove-Variable -Name Username -ErrorAction SilentlyContinue
					Remove-Variable -Name Password -ErrorAction SilentlyContinue
				}
			}
		} # end function Test-UserCredential
		
		function Get-LocalAdministrators 
		{  
			<#
				.SYNOPSIS
					Gets local administrators.
				.DESCRIPTION
					Gets local administratiors on specified computer.
				.PARAMETER  Computer
					The name of the computer.
				.EXAMPLE
					PS C:\> Get-LocalAdministrators -Computer $env:computername
				.INPUTS
					System.String
				.OUTPUTS
					System.String
			#>
			[CmdletBinding()]
			param (
				[Parameter(Mandatory=$true)]
				[string]$Computer
			)  
		
			$admins = Get-WMIObject -class win32_groupuser -computer $computer   
			$admins = $admins | where {$_.groupcomponent -like '*"Administrators"'}  
		
			$admins |Foreach{ 
				$_.partcomponent -match ".+Domain\=(.+)\,Name\=(.+)$" > $nul 
				$matches[1].trim('"') + "\" + $matches[2].trim('"')  
			} 			
		} #end function Get-LocalAdministrators
		
		Function Get-UserSid 
		{
			<#
				.SYNOPSIS
					Gets SID of specified in speciried domain for specified user.
				.DESCRIPTION
					Gets SID of specified in speciried domain for specified user.
				.PARAMETER  Domain
					Domain or Computer to get user SID from.
				.PARAMETER  User
					User name to get SID of.
				.EXAMPLE
					PS C:\> Get-UserSID -domain MWJCOMPUTING -user matt
				.INPUTS
					System.String
				.OUTPUTS
					System.String
				.NOTES
					Written for Matt Johnson's GrrCON 2012 talk PowerShell - Be A Cool Blue Kid.
				.LINK
					www.mwjcomputing.com/resources/grrcon-2012/
				.LINK
					github.com/mwjcomputing/
			#>
			[CmdletBinding()]
			param (
				[Parameter(Mandatory=$true)]
				[string]$domain,
				[Parameter(Mandatory=$true)]
				[string]$user
			)
			$objUser = New-Object System.Security.Principal.NTAccount($domain,$user)
			$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
			$strSID.Value	
		} #end function Get-UserSid
		
		function Get-LocalUsers 
		{
			<#
				.SYNOPSIS
					Gets local users
				.DESCRIPTION
					Gets local users on specified computer.
				.PARAMETER  computer
					Name of the computer
				.EXAMPLE
					PS C:\> Get-LocalUsers -Computer $env:computername
				.INPUTS
					System.String
				.OUTPUTS
					System.String
				.NOTES
					Written for Matt Johnson's GrrCON 2012 talk PowerShell - Be A Cool Blue Kid.
				.LINK
					www.mwjcomputing.com/resources/grrcon-2012/
				.LINK
					github.com/mwjcomputing/
			#>
			[CmdletBinding()]
			param(
				[Parameter(Mandatory=$true)]
				[string]$computer
			)
		
			$adsi = [ADSI]("WinNT://$computer,computer")
			$adsi.name
			
			$users = $adsi.psbase.children | Where {$_.psbase.schemaclassname -eq "User"} | Select Name
			foreach ($user in $users) {
				$user.name
			}
		} #end function Get-LocalUsers
	
	#endregion User Accounts
	
	#region Web
	
		function Test-Uri
		{
			<#
				.NOTES
					Author: Will Steele
					Last Modified Date: 07/27/2012
					
				.EXAMPLE
					Test-Uri -Uri 'http://www.msn.com'
					True
				
				.EXAMPLE
					Test-Uri -Uri 'http:/\hax0r.com'
					False
			#>
			
			param(
				[ValidateNotNullOrEmpty()]
				[String]
				$Uri	
			)
			
			if([System.Uri]::IsWellFormedUriString($Uri, [System.UriKind]::RelativeOrAbsolute))
			{
				[System.Uri]::TryCreate($Uri, [System.UriKind]::RelativeOrAbsolute, [ref] $uri)
			}
			else
			{
				$false
			}
		} # end function Test-Uri

		function Get-WebServerInformation
		{
			<#
				.NOTES
					Author: Will Steele
					
				.EXAMPLE
					Get-WebServerInformation -Uri 'http://www.microsoft.com' -All
					
					IsMutuallyAuthenticated : False
					Cookies                 : {}
					Headers                 : {Accept-Ranges, Content-Length, Cache-Control, Content-Type...}
					SupportsHeaders         : True
					ContentLength           : 1020
					ContentEncoding         : 
					ContentType             : text/html
					CharacterSet            : ISO-8859-1
					Server                  : Microsoft-IIS/7.5
					LastModified            : 3/16/2009 3:35:26 PM
					StatusCode              : OK
					StatusDescription       : OK
					ProtocolVersion         : 1.1
					ResponseUri             : http://www.microsoft.com/
					Method                  : GET
					IsFromCache             : False
					
				.EXAMPLE
					Get-WebServerInformation -Uri 'http://www.google.com' -CharacterSet
					
					ISO-8859-1
					
				.EXAMPLE
					Get-WebServerInformation -Uri 'http://www.kofax.com' -StatusCode -CharacterSet
					
					ISO-8859-1
					OK
					
				.PARAMETER -Uri
					A required parameter indicating the URI of the remote server.
			#>
			
			[CmdletBinding()]
			param(
				[Parameter(
					Mandatory = $true,
					Position = 1,
					ValueFromPipeline = $true
				)]
				[ValidateScript({Test-Uri -Uri $_})]
				[String]
				$Uri,
				
				[Switch]
				$All = $true,
				
				[Switch]
				$CharacterSet = $false,
						
				[Switch]
				$ContentEncoding = $false,

				[Switch]
				$ContentLength = $false,		
				
				[Switch]
				$ContentType = $false,
				
				[Switch]
				$Cookies = $false,		
				
				[Switch]
				$Headers = $false,
				
				[Switch]
				$IsFromCache = $false,		
				
				[Switch]
				$IsMutuallyAuthenticated = $false,
				
				[Switch]
				$LastModified = $false,
				
				[Switch]
				$Method = $false,			
				
				[Switch]
				$ProtocolVersion = $false,
				
				[Switch]
				$ResponseUri = $false,		
						
				[Switch]
				$Server = $false,
				
				[Switch]
				$StatusCode = $false,
				
				[Switch]
				$StatusDescription = $false,
				
				[Switch]
				$SupportsHeaders = $false		
			)

			try
			{
				$response = ([net.webrequest]::create($Uri)).GetResponse()
			}
			catch 
			{
				throw $Error[-1]
			}

			if($All)
			{
				$response
			}
			if($CharacterSet)
			{
				$response.CharacterSet
			}
			if($ContentEncoding)
			{
				$response.ContentEncoding
			}
			if($ContentLength)
			{
				$response.ContentLenght
			}
			if($ContentType)
			{
				$response.ContentType
			}
			if($Cookies)
			{
				$response.Cookies
			}
			if($Headers)
			{
				$response.Headers
			}
			if($IsFromCache)
			{
				$response.IsFromCache
			}
			if($IsMutuallyAuthenticated)
			{
				$response.IsMutuallyAuthenticated
			}
			if($LastModified)
			{
				$response.LastModified
			}
			if($Method)
			{
				$response.Method
			}
			if($ProtocolVersion)
			{
				$response.ProtocolVersion
			}
			if($ResponseUri)
			{
				$response.ResponseUri
			}
			if($Server)
			{
				$response.Server
			}
			if($StatusCode)
			{
				$response.StatusCode
			}
			if($StatusDescription)
			{
				$response.StatusDescription
			}
			if($SupportsHeaders)
			{
				$response.SupportsHeaders
			}
		} # end function Get-WebServerInformation
	
	#endregion Web

#endregion AuditFunctions

#region ModuleExports
	#region UserAccountExport
		Export-ModuleMember -Function "Test-Uri"
		Export-ModuleMember -Function "Get-WebServerInformation"
		Export-ModuleMember -Function "Get-UserSid"
		Export-ModuleMember -Function "Get-LocalUsers"
	#endregion UserAccountExport
	#region WebExport
		Export-ModuleMember -Function "Test-UserCredential"
		Export-ModuleMember -Function "Get-LocalAdministrators"
	#endregion WebExport
#endregion ModuleExports
